home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / nasanets.zip / DRIBBLE.C < prev    next >
C/C++ Source or Header  |  1990-06-07  |  21KB  |  589 lines

  1. /*=============================*/
  2. /*           NETS              */
  3. /*                             */
  4. /* a product of the AI Section */
  5. /* NASA, Johnson Space Center  */
  6. /*                             */
  7. /* principal author:           */
  8. /*       Paul Baffes           */
  9. /*                             */
  10. /* contributing authors:       */
  11. /*      Bryan Dulock           */
  12. /*      Chris Ortiz            */
  13. /*=============================*/
  14.  
  15.  
  16. /*
  17. ----------------------------------------------------------------------
  18.   Code For Dribbling output to User (Prefix = D_)
  19. ----------------------------------------------------------------------
  20.   This code is divided into 4 major sections:
  21.  
  22.   (1) include files
  23.   (2) externed functions
  24.   (3) global variables
  25.   (4) subroutines
  26.  
  27.   Each section is further explained below.
  28. ----------------------------------------------------------------------
  29. */
  30.  
  31.  
  32. /*
  33. ----------------------------------------------------------------------
  34.   INCLUDE FILES
  35. ----------------------------------------------------------------------
  36. */
  37. #include "common.h"
  38. #include "weights.h"
  39. #include "layer.h"
  40. #include "net.h"
  41. #include "netio.h"
  42.  
  43.  
  44. /*
  45. ----------------------------------------------------------------------
  46.   EXTERNED FUNCTIONS AND GLOBALS
  47. ----------------------------------------------------------------------
  48.   Below are the functions defined in other files which are used by the
  49.   code here. They are organized by section.
  50. ----------------------------------------------------------------------
  51. */
  52. extern  void    IO_my_get_string();
  53. extern  float   C_Sint_to_float();
  54. extern  void    N_save_wts();
  55. extern  void    N_query_net();
  56. extern  void    IO_print();
  57. extern  void    IO_insert_format();
  58.  
  59. extern  char    IO_wkstr[MAX_LINE_SIZE];
  60. extern  char    IO_str[MAX_LINE_SIZE];
  61.  
  62.  
  63. /*
  64. ----------------------------------------------------------------------
  65.   GLOBALS
  66. ----------------------------------------------------------------------
  67.   The list of globals here are for the dribble facility of NETS. The idea 
  68.   is to be able to save error values and weights and test case results 
  69.   DURING the training to see how things are going. Five files are needed, 
  70.   and eight flags. Four of the flags are referenced in "teach.c" to  
  71.   determine if the D_dribble function should be called.
  72. ----------------------------------------------------------------------
  73. */
  74. char           maxerr_file[MAX_WORD_SIZE]; /* These three strings used  */
  75. char           rmserr_file[MAX_WORD_SIZE]; /* for dribbling OUTPUT as   */
  76. char           weights_file[MAX_WORD_SIZE];/* the net runs.             */
  77. char           tests_file[MAX_WORD_SIZE];  
  78. char           tests_in[MAX_WORD_SIZE];    /* INPUT file for test runs  */
  79.  
  80. int            SAVE_MAXERR;    /* These eight used as flags for the     */
  81. int            SAVE_RMSERR;    /* dribble option                        */
  82. int            SAVE_WEIGHTS;   
  83. int            SAVE_TESTS;
  84. int            MOD_MAXERR;     /* the MOD globals dictate how often the */
  85. int            MOD_RMSERR;     /* the files will be updated (in cycles) */
  86. int            MOD_WEIGHTS;    
  87. int            MOD_TESTS;
  88.  
  89.  
  90. /*
  91. ======================================================================
  92.   ROUTINES IN BUILDNET.C                                                   
  93. ======================================================================
  94.   The routines in this file are grouped below by function.  Each routine
  95.   is prefixed by the string "D_" indicating that it is defined in the 
  96.   "buildnet.c" file.  The types returned by the routines are also shown 
  97.   here so that cross checking is more easily done between these functions
  98.   and the other files which intern them.
  99.  
  100.  
  101.   Type Returned                 Routine                                 
  102.   -------------                 -------       
  103.     void                        D_initialize                          
  104.     void                        D_dribble
  105.     int                         D_set_dribble
  106.     void                        D_dribble_status
  107.     void                        D_maxerr_dribble
  108.     void                        D_rmserr_dribble
  109.     void                        D_weights_dribble
  110.     void                        D_tests_dribble
  111. ======================================================================
  112. */
  113.  
  114.  
  115. void  D_initialize()
  116. /*
  117. ----------------------------------------------------------------------
  118.   The beginning values of the dribble filenames are set
  119.   to the empty string by this routine.                 
  120. ----------------------------------------------------------------------
  121. */
  122. BEGIN
  123.    /*--------------------------------*/
  124.    /* set dribble parameters to NULL */
  125.    /*--------------------------------*/
  126.    maxerr_file[0]  = ENDSTRING;  
  127.    rmserr_file[0]  = ENDSTRING;
  128.    weights_file[0] = ENDSTRING;
  129.    tests_file[0]   = ENDSTRING;
  130.    tests_in[0]     = ENDSTRING;
  131.  
  132.    /*------------------------------------------*/
  133.    /* set the dribble parameters to OFF, and 1 */
  134.    /*------------------------------------------*/
  135.    SAVE_MAXERR  = FALSE;
  136.    SAVE_RMSERR  = FALSE;
  137.    SAVE_WEIGHTS = FALSE;
  138.    SAVE_TESTS   = FALSE;
  139.    MOD_MAXERR   = 1;
  140.    MOD_RMSERR   = 1;
  141.    MOD_WEIGHTS  = 1;
  142.    MOD_TESTS    = 1;
  143.  
  144. END /* D_initialize */
  145.  
  146.  
  147. void  D_dribble_status()
  148. /*
  149. ----------------------------------------------------------------------
  150.   Prints out a prompt indicating the status of the dribble parameters.
  151.   For any parameters which are ON, the corresponding MOD and filename
  152.   values are also printed. Then, it asks whether or not to continue
  153.   prompting the user for info (namely, it asks whether or not the
  154.   user wants to change the values of the parameters).
  155. ----------------------------------------------------------------------
  156. */
  157. BEGIN
  158.    void  D_maxerr_dribble(), D_weights_dribble(), D_tests_dribble(),
  159.          D_rmserr_dribble();
  160.    char  temp_str[MAX_WORD_SIZE];
  161.    
  162.    /*----------------------------*/
  163.    /* first print header of info */
  164.    /*----------------------------*/
  165.    sprintf(IO_str, "\n   Current Dribble Parameters Are:");
  166.    IO_print(0);
  167.    sprintf(IO_str, "\n     Parameter  State  Cycles  Output File");
  168.    IO_print(0);
  169.    sprintf(IO_str, "\n                -----  ------  -----------");
  170.    IO_print(0);
  171.    
  172.    /*---------------------------------------*/
  173.    /* then print status of three parameters */
  174.    /*---------------------------------------*/
  175.    if (SAVE_MAXERR == TRUE)
  176.       sprintf(IO_str, "\n     Max Error: ON %8d     %s", MOD_MAXERR, maxerr_file);
  177.    else sprintf(IO_str, "\n     Max Error: OFF");
  178.    IO_print(0);
  179.    if (SAVE_RMSERR == TRUE)
  180.       sprintf(IO_str, "\n     RMS Error: ON %8d     %s", MOD_RMSERR, rmserr_file);
  181.    else sprintf(IO_str, "\n     RMS Error: OFF");
  182.    IO_print(0);
  183.    if (SAVE_WEIGHTS == TRUE)
  184.       sprintf(IO_str, "\n     Weights:   ON %8d     %s", MOD_WEIGHTS, weights_file);
  185.    else sprintf(IO_str, "\n     Weights:   OFF");
  186.    IO_print(0);
  187.    if (SAVE_TESTS == TRUE) BEGIN
  188.       sprintf(IO_str, "\n     Tests:     ON %8d     %s", MOD_TESTS, tests_file);
  189.       IO_print(0);
  190.       sprintf(IO_str, " (test file: %s)", tests_in);
  191.    ENDIF
  192.    else sprintf(IO_str, "\n     Tests:     OFF");
  193.    IO_print(0);
  194.          
  195.    /*--------------------------------------------------*/
  196.    /* finally, prompt user for update of dribble parms */
  197.    /*--------------------------------------------------*/
  198.    sprintf(IO_str, "\n\n   Change dribble parameters(y/n default=n): ");
  199.    IO_print(0);
  200.    IO_my_get_string(temp_str);
  201.    if ((temp_str[0] == 'y') || (temp_str[0] == 'Y')) BEGIN
  202.       D_maxerr_dribble();
  203.       D_rmserr_dribble();
  204.       D_weights_dribble();
  205.       D_tests_dribble();
  206.    ENDIF
  207.  
  208. END /* D_dribble_status */
  209.  
  210.  
  211. void  D_maxerr_dribble()
  212. /*
  213. ----------------------------------------------------------------------
  214.    This routine prompts the user for info concerning whether or not to
  215.    turn ON or OFF the SAVE_WEIGHTS flag (of NETMAIN.C) and, consequently,
  216.    for the filename to use as a repository for the weights as the net
  217.    is learning.
  218. ----------------------------------------------------------------------
  219. */
  220. BEGIN
  221.    int          D_set_dribble();
  222.    FILE         *fp;
  223.    static char  name[11] = "Max Errors";
  224.  
  225.    /*-------------------------*/
  226.    /* get new parameter value */
  227.    /*-------------------------*/
  228.    SAVE_MAXERR = D_set_dribble(SAVE_MAXERR, &MOD_MAXERR,
  229.                                 name, maxerr_file);
  230.  
  231.    /*--------------------------------------*/
  232.    /* if set, the get filename for errors  */
  233.    /* then open file and write out header  */
  234.    /*--------------------------------------*/
  235.    if (SAVE_MAXERR == TRUE) BEGIN
  236.       if ((fp = fopen(maxerr_file, "wt")) == NULL) BEGIN
  237.          sprintf(IO_str, "\n*** error opening file %s ***", maxerr_file);
  238.          IO_print(0);
  239.          SAVE_MAXERR = FALSE;
  240.          return;
  241.       ENDIF
  242.       fprintf(fp, "-- Max Errors Dribble File --\n");
  243.       fclose(fp);
  244.    ENDIF
  245.  
  246. END /* D_maxerr_dribble */
  247.  
  248.  
  249. void  D_rmserr_dribble()
  250. /*
  251. ----------------------------------------------------------------------
  252.    This routine prompts the user for info concerning whether or not to
  253.    turn ON or OFF the SAVE_WEIGHTS flag (of NETMAIN.C) and, consequently,
  254.    for the filename to use as a repository for the weights as the net
  255.    is learning.
  256. ----------------------------------------------------------------------
  257. */
  258. BEGIN
  259.    int          D_set_dribble();
  260.    FILE         *fp;
  261.    static char  name[11] = "RMS Errors";
  262.  
  263.    /*-------------------------*/
  264.    /* get new parameter value */
  265.    /*-------------------------*/
  266.    SAVE_RMSERR = D_set_dribble(SAVE_RMSERR, &MOD_RMSERR,
  267.                                 name, rmserr_file);
  268.  
  269.    /*--------------------------------------*/
  270.    /* if set, the get filename for errors  */
  271.    /* then open file and write out header  */
  272.    /*--------------------------------------*/
  273.    if (SAVE_RMSERR == TRUE) BEGIN
  274.       if ((fp = fopen(rmserr_file, "wt")) == NULL) BEGIN
  275.          sprintf(IO_str, "\n*** error opening file %s ***", rmserr_file);
  276.          IO_print(0);
  277.          SAVE_RMSERR = FALSE;
  278.          return;
  279.       ENDIF
  280.       fprintf(fp, "-- RMS Errors Dribble File --\n");
  281.       fclose(fp);
  282.    ENDIF
  283.  
  284. END /* D_rmserr_dribble */
  285.  
  286.  
  287. void  D_weights_dribble()
  288. /*
  289. ----------------------------------------------------------------------
  290.    This routine prompts the user for info concerning whether or not to
  291.    turn ON or OFF the SAVE_WEIGHTS flag (of NETMAIN.C) and, consequently,
  292.    for the filename to use as a repository for the weights as the net
  293.    is learning.
  294. ----------------------------------------------------------------------
  295. */
  296. BEGIN
  297.    int          D_set_dribble();
  298.    static char  name[8] = "Weights";
  299.  
  300.    /*----------------------------*/
  301.    /* set parameter to new value */
  302.    /*----------------------------*/
  303.     SAVE_WEIGHTS = D_set_dribble(SAVE_WEIGHTS, &MOD_WEIGHTS, 
  304.                                   name, weights_file);
  305.        
  306. END /* D_weights_dribble */
  307.  
  308.  
  309. void  D_tests_dribble()
  310. /*
  311. ----------------------------------------------------------------------
  312.    This routine prompts the user for info concerning whether or not to
  313.    turn ON or OFF the SAVE_TESTS flag (of NETMAIN.C) and, consequently,
  314.    for the filename to use as a repository for the test cases as the net
  315.    is learning.
  316. ----------------------------------------------------------------------
  317. */
  318. BEGIN
  319.    int          D_set_dribble();
  320.    FILE         *fp;
  321.    char         temp_str[MAX_WORD_SIZE];
  322.    static char  name[7] = "Tests";
  323.    
  324.  
  325.    /*-------------------------*/
  326.    /* get new parameter value */
  327.    /*-------------------------*/
  328.    SAVE_TESTS = D_set_dribble(SAVE_TESTS, &MOD_TESTS, 
  329.                                name, tests_file);
  330.  
  331.    /*--------------------------------------*/
  332.    /* if set, the get filename for errors  */
  333.    /* then open file and write out header  */
  334.    /*--------------------------------------*/
  335.    if (SAVE_TESTS == TRUE) BEGIN
  336.       sprintf(IO_str, "\n      Enter INPUT filename for testing network");
  337.       IO_print(0);
  338.       sprintf(IO_str, "(default=%s): ", tests_in);
  339.       IO_print(0);
  340.       IO_my_get_string(temp_str);
  341.  
  342.       /*-------------------------------------*/
  343.       /* set filename if default is not used */
  344.       /*-------------------------------------*/
  345.       if (temp_str[0] != ENDSTRING) strcpy(tests_in, temp_str);
  346.          
  347.       /*----------------------------------------*/
  348.       /* after assigning tests_in, check to see */
  349.       /* if it's still empty (default tests_in  */
  350.       /* is empty and would not be set above)   */
  351.       /*----------------------------------------*/
  352.       if (tests_in[0] == ENDSTRING) BEGIN
  353.          sprintf(IO_str, "\n      *** can't open file  ***");
  354.          IO_print(0);
  355.          SAVE_TESTS = FALSE;
  356.          return;
  357.       ENDIF
  358.  
  359.       fp = fopen(tests_file, "wt");
  360.       fprintf(fp, "-- Tests Dribble File --\n");
  361.       fclose(fp);
  362.    ENDIF
  363.    
  364. END /* D_tests_dribble */
  365.  
  366.  
  367. int  D_set_dribble(last_val, mod_val, parm_name, filename)
  368. int   last_val;
  369. int   *mod_val;
  370. char  *parm_name, *filename;
  371. /*
  372. ----------------------------------------------------------------------
  373.    Takes care of prompting the user for any of the dribble parameters
  374.    which can be set to ON or OFF. A return value is provided which 
  375.    indicates what the new value of the parameter should be.
  376.    
  377.    Note also that the incoming "filename" parameter may be altered by
  378.    this routine if the user answers "ON" to the parameter and answers
  379.    a new string value for the dribble filename.
  380.    
  381.    Finally, the mod_val parameter is passed in as a pointer to one of
  382.    the three "MOD_..." globals defined in NETMAIN.C (eg MOD_ERRORS).
  383.    If a filename is successfully entered by the user, then the last 
  384.    part of this routine updates the corresponding mod number, again
  385.    according to user response.
  386. ----------------------------------------------------------------------
  387. */
  388. BEGIN
  389.    int   rval, old_mod;
  390.    char  temp_str[MAX_WORD_SIZE];
  391.  
  392.    /*---------------------------------------*/
  393.    /* print prompt with old parameter value */
  394.    /*---------------------------------------*/
  395.    sprintf(IO_str, "\n   Set %s parameter", parm_name);
  396.    IO_print(0);
  397.    sprintf(IO_str, "(default=%s): ", (last_val == TRUE ? "ON" : "OFF"));
  398.    IO_print(0);
  399.    IO_my_get_string(temp_str);
  400.  
  401.    /*-------------------------------------*/
  402.    /* set return value by user's response */
  403.    /*-------------------------------------*/
  404.    if (temp_str[0] == ENDSTRING)
  405.       rval = last_val;
  406.    else if ( (strcmp(temp_str, "on") == 0) || (strcmp(temp_str, "ON") == 0) )
  407.       rval = TRUE;
  408.    else
  409.       rval = FALSE;
  410.       
  411.    /*------------------------------------*/
  412.    /* if set, the get filename for the   */
  413.    /* dribble output with old as default */
  414.    /*------------------------------------*/
  415.    if (rval == TRUE) BEGIN
  416.       sprintf(IO_str, "\n      Enter OUTPUT filename for saving %s", parm_name);
  417.       IO_print(0);
  418.       sprintf(IO_str, "(default=%s): ", filename);
  419.       IO_print(0);
  420.       IO_my_get_string(temp_str);
  421.  
  422.       /*-------------------------------------*/
  423.       /* set filename if default is not used */
  424.       /*-------------------------------------*/
  425.       if (temp_str[0] != ENDSTRING) strcpy(filename, temp_str);
  426.          
  427.       /*----------------------------------------*/
  428.       /* after assigning filename, check to see */
  429.       /* if it's still empty (default filename  */
  430.       /* is empty and would not be set above)   */
  431.       /*----------------------------------------*/
  432.       if (filename[0] == ENDSTRING) BEGIN
  433.          sprintf(IO_str, "\n      *** can't open file  ***");
  434.          IO_print(0);
  435.          rval = FALSE;
  436.       ENDIF
  437.    ENDIF
  438.    
  439.    /*------------------------------------------*/
  440.    /* if all still go for change, then get new */
  441.    /* mod value for saving to the given file   */
  442.    /*------------------------------------------*/
  443.    old_mod = *mod_val;
  444.    if (rval == TRUE) BEGIN
  445.       sprintf(IO_str, "\n      Enter cycle increment for saving %s", parm_name);
  446.       IO_print(0);
  447.       sprintf(IO_str, "(default=%d): ", *mod_val);
  448.       IO_print(0);
  449.       if (gets(temp_str) != NULL)
  450.          sscanf(temp_str, "%d", mod_val);
  451.       if (*mod_val < 1) BEGIN
  452.          sprintf(IO_str, "\n      *** cycle number cannot be < 1; default used ***\n");
  453.          IO_print(0);
  454.          *mod_val = old_mod;
  455.       ENDIF
  456.    ENDIF
  457.    
  458.    return(rval);
  459.  
  460. END /* D_set_dribble */
  461.  
  462.  
  463. void  D_dribble(ptr_net, num_cycles, cur_error, grad_err)
  464. Net    *ptr_net;
  465. int    num_cycles;
  466. Sint   cur_error;
  467. float  grad_err;
  468. /*
  469. ----------------------------------------------------------------------
  470.   This routine takes the current cycle number and error value as input
  471.   from the T_teach_net routine and prints out information, if any, which
  472.   should appear in the dribble files. This is done by first noting if 
  473.   any of the MOD numbers for the dribble 
  474. ----------------------------------------------------------------------
  475. */
  476. BEGIN
  477.    FILE  *fp;
  478.    void  D_next_wts_file();
  479.  
  480.  
  481.    /*---------------------------------------------*/
  482.    /* if SAVE_MAXERR is ON and we're at the right */
  483.    /* cycle,  output "(cycle number, max error)"  */
  484.    /*---------------------------------------------*/
  485.    if ( (SAVE_MAXERR == TRUE)
  486.         && ((num_cycles % MOD_MAXERR) == 0) ) BEGIN
  487.       fp = fopen(maxerr_file, "at");
  488.       sprintf(IO_wkstr, "\n(%d %%.f)", num_cycles);
  489.       IO_insert_format(IO_wkstr);
  490.       fprintf(fp, IO_wkstr, C_Sint_to_float(cur_error) );
  491.       fclose(fp);
  492.    ENDIF
  493.    
  494.    /*---------------------------------------------*/
  495.    /* if SAVE_RMSERR is ON and we're at the right */
  496.    /* cycle,  output "(cycle number, RMS error)"  */
  497.    /*---------------------------------------------*/
  498.    if ( (SAVE_RMSERR == TRUE)
  499.         && ((num_cycles % MOD_RMSERR) == 0) ) BEGIN
  500.       fp = fopen(rmserr_file, "at");
  501.       sprintf(IO_wkstr, "\n(%d %%.f)", num_cycles);
  502.       IO_insert_format(IO_wkstr);
  503.       fprintf(fp, IO_wkstr, grad_err);
  504.       fclose(fp);
  505.    ENDIF
  506.    
  507.    /*----------------------------------------------*/
  508.    /* if SAVE_WEIGHTS is ON and we're at the right */
  509.    /* cycle, then printout a "please wait..." mesg */
  510.    /* and save the weights using N_save_wts        */
  511.    /*----------------------------------------------*/
  512.    if ( (SAVE_WEIGHTS == TRUE)
  513.         && ((num_cycles % MOD_WEIGHTS) == 0) ) BEGIN
  514.       /* D_next_wts_file(weights_file); */
  515.       sprintf(IO_str, "\n*** currently dribbling weights to %s...", weights_file);
  516.       IO_print(0);
  517.       N_save_wts(ptr_net, weights_file, FAST_FORMAT);
  518.       sprintf(IO_str, "done.");
  519.       IO_print(0);
  520.    ENDIF
  521.    
  522.    /*--------------------------------------------*/
  523.    /* If SAVE_TESTS is ON and we're at the right */
  524.    /* cycle, then append a test case to the end  */
  525.    /* of the tests_file, along with the cycle    */
  526.    /*--------------------------------------------*/
  527.    if ( (SAVE_TESTS == TRUE)
  528.         && ((num_cycles % MOD_TESTS) == 0) ) BEGIN
  529.       /*----------------------------------------*/
  530.       /* open file, output cycle number and "(" */
  531.       /*----------------------------------------*/
  532.       fp = fopen(tests_file, "at");
  533.       fprintf(fp, "\n*** CYCLE: %d ***", num_cycles);
  534.  
  535.       /*----------------------------------------*/
  536.       /* output results from propagation; close */
  537.       /*----------------------------------------*/
  538.       N_query_net(ptr_net, tests_in, fp, -1);
  539.       fclose(fp);
  540.    ENDIF
  541.  
  542. END /* D_dribble */
  543.  
  544.  
  545. void  D_next_wts_file(filename)
  546. char *filename;
  547. /*
  548. ----------------------------------------------------------------------
  549.   Right now, this routine is functional, but not part of the normal
  550.   NETS program (ie, it isn't documented anywhere). It is only called
  551.   by the D_dribble routine and its function is to save the weights
  552.   to DIFFERENT files during learning rather than to the same file over
  553.   and over again. I had thought this would be useful to be able to see
  554.   weights from different stages of learning, but so far this feature 
  555.   has done little more than create lots of useless files.
  556.   Note that the "tail" variable is static. Thus this code currently
  557.   only works for the first learning cycle, ie, if you create a new
  558.   network after saving some weights, tail will pick up where it left
  559.   off.
  560. ----------------------------------------------------------------------
  561. */
  562. BEGIN
  563.    static  int tail = 1;
  564.    int     i;
  565.    char    temp[MAX_WORD_SIZE];
  566.    
  567.    if (filename[0] == ENDSTRING) BEGIN
  568.       tail = 1;
  569.       return;
  570.    ENDIF
  571.    
  572.    for (i = 0; i < MAX_WORD_SIZE; i++) BEGIN
  573.       if (filename[i] == '.') break;
  574.       temp[i] = filename[i];
  575.    ENDFOR
  576.    temp[i] = ENDSTRING;
  577.    
  578.    if (tail < 10)
  579.       sprintf(filename, "%s.00%d", temp, tail);
  580.    else if (tail < 100)
  581.       sprintf(filename, "%s.0%d", temp, tail);
  582.    else 
  583.       sprintf(filename, "%s.%d", temp, tail);
  584.       
  585.    tail++;
  586.  
  587. END /* D_nextawts_file */
  588.  
  589.